﻿Imports System.ComponentModel

Public Class MainForm

    'TODO: Need to hide command process windows
    'TODO: Need disclaimer about bricking your device!

    Private Property Device As String
    Private Property DeviceState As String

#Region "Form Events"

    ''' <summary>
    ''' Event Handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load

        ' Start the ADB Server in the background
        tslStatus.Text = "Starting ADB Server"
        Dim bgw As New BackgroundWorker
        AddHandler bgw.DoWork, AddressOf Me.bgw_DoWork
        AddHandler bgw.RunWorkerCompleted, AddressOf Me.bgw_RunWorkerCompleted
        bgw.RunWorkerAsync()

    End Sub

    ''' <summary>
    ''' Event Handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub MainForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        KillADBServer()
    End Sub

#End Region

#Region "ADB Server Control"

    ''' <summary>
    ''' Event Handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)

        Dim mySender As BackgroundWorker = CType(sender, BackgroundWorker)
        e.Result = StartADBServer()

    End Sub

    ''' <summary>
    ''' Event Handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)

        Dim msg As String

        If CBool(e.Result) = False Then
            msg = "ADB Server failed to start"
        Else
            msg = "ADB Server started successfully"
            btnChangeADB_Click(Me, Nothing)        ' Refresh ADB devices
        End If

        tslStatus.Text = msg

    End Sub

    ''' <summary>
    ''' Start the ADB Server. 
    ''' </summary>
    ''' <returns>True if server started successfully, false if not.</returns>
    ''' <remarks></remarks>
    Private Function StartADBServer() As Boolean

        Dim p As New Process
        StartADBServer = False

        Try
            p.StartInfo.Arguments = "start-server"
            p.StartInfo.FileName = "platform-tools\adb.exe"
            p.StartInfo.UseShellExecute = True
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
            p.Start()
            p.WaitForExit()

            'TODO: Should check here if the server started correctly
            StartADBServer = True

        Catch ex As Exception
            StartADBServer = False

        Finally
            p.Close()

        End Try

    End Function

    ''' <summary>
    ''' Kill the ADB Server. 
    ''' </summary>
    ''' <returns>True if server started successfully, false if not.</returns>
    ''' <remarks></remarks>
    Private Function KillADBServer() As Boolean

        Dim p As New Process
        KillADBServer = False

        Try
            p.StartInfo.Arguments = "kill-server"
            p.StartInfo.FileName = "platform-tools\adb.exe"
            p.StartInfo.UseShellExecute = True
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
            p.Start()
            p.WaitForExit()

            'TODO: Should check here if the server stopped correctly
            KillADBServer = True

        Catch ex As Exception
            KillADBServer = False

        Finally
            p.Close()

        End Try

    End Function


#End Region

#Region "Form Control Events"

    ''' <summary>
    ''' Event Handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnChangeADB_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnChangeADB.Click

        Dim devs As List(Of String) = androidADBDevices()
        tscbADBDevices.Enabled = True

        tscbADBDevices.Items.Clear()
        For Each dev As String In devs
            tscbADBDevices.Items.Add(dev)
        Next

    End Sub

    ''' <summary>
    ''' Event Handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnFastboot_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFastboot.Click

        Dim serialNumber As String = tscbADBDevices.SelectedItem.ToString
        If MsgBox("Are you sure you want to reboot this device into FastBoot? : " & serialNumber, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
            Fastboot(serialNumber)
        End If

    End Sub

    ''' <summary>
    ''' Event Handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub tscbADBDevices_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles tscbADBDevices.SelectedIndexChanged

        'TODO: Should check that the selected ADB devices is valid (i.e. can communicate) before enabling the button

        If tscbADBDevices.SelectedIndex >= 0 Then
            btnFastboot.Enabled = True
            tscbADBDevices.Enabled = False
            Device = tscbADBDevices.SelectedItem.ToString
        End If

    End Sub

#End Region


    ''' <summary>
    ''' Get a list of currently connected android ADB devices
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function androidADBDevices() As List(Of String)

        androidADBDevices = New List(Of String)

        Dim p As New Process
        Try
            p.StartInfo.Arguments = "devices"
            TweakProcess(p)

            p.Start()
            p.WaitForExit()

            Do Until p.StandardOutput.Peek = -1
                Dim str As String = p.StandardOutput.ReadLine
                If str <> "List of devices attached " And str <> "" Then
                    androidADBDevices.Add(str.Split(CChar(vbTab))(0))
                End If
            Loop

        Catch ex As Exception

        Finally
            p.Close()

        End Try

    End Function

    ''' <summary>
    ''' Get a list of currently connected android fastboot devices
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function androidFastbootDevices() As List(Of String)

        androidFastbootDevices = New List(Of String)

        Dim p As New Process
        Try
            p.StartInfo.Arguments = "devices"
            TweakProcess(p)
            p.Start()
            p.WaitForExit()

            Do Until p.StandardOutput.Peek = -1
                Dim str As String = p.StandardOutput.ReadLine
                If str <> "List of devices attached " And str <> "" Then
                    androidFastbootDevices.Add(str)
                End If
            Loop

        Catch ex As Exception

        Finally
            p.Close()

        End Try

    End Function

    ''' <summary>
    ''' Reboot the device with the given serial number into the bootloader
    ''' </summary>
    ''' <param name="serialNumber"></param>
    ''' <remarks></remarks>
    Private Sub Fastboot(ByVal serialNumber As String)

        Dim p As New Process
        Try
            p.StartInfo.Arguments = "-s " & serialNumber & " reboot bootloader"
            TweakProcess(p)

            p.Start()
            p.WaitForExit()

        Catch ex As Exception

        Finally
            p.Close()

        End Try

    End Sub

    ''' <summary>
    ''' Perform common property Set's on the 
    ''' </summary>
    ''' <param name="p"></param>
    ''' <remarks></remarks>
    Private Sub TweakProcess(ByRef p As Process)

        p.StartInfo.FileName = "platform-tools\adb.exe"
        p.StartInfo.RedirectStandardError = True
        p.StartInfo.RedirectStandardOutput = True
        p.StartInfo.UseShellExecute = False
        p.StartInfo.CreateNoWindow = False
        p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized

    End Sub

End Class
